// 封装图片懒加载指令 并且以插件的形式
// vue3有什么变化？

// 插件？
// 1. 定义插件 2.注册插件
// 定义插件 俩种方式  对象定义法  函数定义法

/*
// vue2 定义
const plugin = {
  install (Vue) {
    // 插件的逻辑
  }
}
// 如果是函数定义的话 函数本身会被当成 install方法执行
function plugin(Vue){
  // 插件的逻辑
}
// 注册 调用use方法的时候 会自动执行插件的install方法并且会自动把Vue构造函数传入
// install方法中

Vue.use(plugin)
*/

/**
  vue3
  先定义 再注册
  定义的俩种写法也没有变化  对象定义法 + 函数定义法

  const plugin = {
    install(app){
      // 插件逻辑
    }
  }
  // 当执行use方法的时候 应用实例对象app会自动当成实参传入install方法
  createApp().use(plugin)
 */

/**
 * vue2
 Vue.direactive('指令名称',{
   inserted(el, binding){
    // el: 指令挂在哪个元素 就指的是那个dom对象
    // binding.value: 指令等于号后面的表达式的值
   }
 })
 <img v-指令名称="表达式"/>

 vue3
 createApp() -> app
 app.direactive('指令名称',{
   mounted(el, binding){
     // el: 指令挂在哪个元素 就指的是那个dom对象
     // binding.value: 指令等于号后面的表达式的值
   }
 })
 */
import { useIntersectionObserver } from '@vueuse/core'
const plugin = {
  install (app) {
    // console.log('插件已经注册好了', app)
    // 定义指令
    app.directive('img-lazy', {
      mounted (el, binding) {
        // console.log(el, binding.value)
        // 在这里写核心逻辑 架子已经都搭好了
        // 核心思想：监控图片是否进入到视口区域 如果进来才发送图片请求
        // 技术点：1. 如何知道图片进入到视口了？ 2. 如何发送请求？
        //            vueUse                   img.src = 'url'
        const { stop } = useIntersectionObserver(
          el,
          ([{ isIntersecting }], observerElement) => {
            // isIntersecting: 布尔值 true代表监听的元素已经进入了视口
            // false代表监听的元素离开了视口
            // 这个函数的监听很精确 不光可以横向 还有纵向
            // 这个回调在每次进入离开视口都会不断执行
            // 图片一旦请求回来之后 就不需要你这个监听逻辑了？
            // console.log(isIntersecting)
            if (isIntersecting === true) {
              // ? 当前图片进入视口了 赋值src正式发送图片请求
              el.src = binding.value
              // 优化 停止监听
              stop()
            }
          },
          // threshold: 0 - 1 值越小 代表进入的视口的面积越小就会触发
          // 反之越大触发 0 img刚刚露头就触发  1 完全暴露在视口中才会触发
          { threshold: 0 }
        )
      }
    })
  }
}

export default plugin
